/**
 * 神州信息(2012)
 */
package net.abbp.mtr;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.JFrame;

import net.abbp.core.util.NumberUtils;
import net.abbp.dao.DaoFactory;
import net.abbp.dao.IDao;
import net.abbp.mtr.config.ChannelManager;
import net.abbp.mtr.data.Record;
import net.abbp.mtr.event.DataArriveEvent;
import net.abbp.mtr.event.IDataArriveListener;
import net.abbp.mtr.event.SerialEvent;
import net.abbp.mtr.event.SerialListener;
import net.abbp.plugins.quartz.QuartzManager;
import net.abbp.sms.SmsSender;
import net.abbp.watchkeeper.Linkman;
import net.abbp.watchkeeper.LinkmanPane;
import net.abbp.watchkeeper.WatchKeeperEditor;
import net.abbp.watchkeeper.WatchKeeperManager;

import com.jidesoft.action.DefaultDockableBarDockableHolder;
import com.jidesoft.swing.JideTabbedPane;
import com.jidesoft.utils.Lm;

/**
 * 温度采集主窗体
 * 
 * @version 1.0
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since ABBP 1.0
 * 
 *        Date：Apr 8, 2012
 */
public class MainMtrWindow extends DefaultDockableBarDockableHolder implements SerialListener {
    private static final long serialVersionUID = 3310285684217738637L;

    static {
        Lm.verifyLicense("Digital China", "BriskBVM", "eJYwQanZJAjb5eac7o2Pe1WeZ1htbGP1");
    }
    // 事件监听器列表
    private List<IDataArriveListener> listenerList = new ArrayList<IDataArriveListener>();
    // private Scheduler sched;
    // 缓冲数据
    private String bufferData = "";
    // 数据长度
    private static final int DATA_LENGTH = 6;
    private IDao dao = DaoFactory.INSTANCE.newDao();
    // 短信容器
    ArrayBlockingQueue<SmsRecord> smsQuery = new ArrayBlockingQueue<SmsRecord>(64, true);

    // 短信结构
    private class SmsRecord {
        private String channel;
        private double value;

        SmsRecord(String channel, double value) {
            this.channel = channel;
            this.value = value;
        }
    }

    public MainMtrWindow() {
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        this.setPreferredSize(new Dimension(screenSize.width, screenSize.height));
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("温度监测");
        this.initialize();

        this.pack();

        this.initPeriodicDaq();

        // 创建多线程
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(new Runnable() {

            @Override
            public void run() {
                while (true) {
                    try {
                        SmsRecord r = smsQuery.take();

                        String message = ChannelManager.INSTANCE.getChannelConfig(r.channel) + "温度超限,当前温度为:" + r.value
                                + "°";
                        List<Linkman> dists = WatchKeeperManager.INSTANCE.getLinkmans();

                        // 发送短信
                        for (Linkman mpi : dists) {
                            System.out.println("发送号码:" + mpi.getPhone());
                            System.out.println("发送短信：" + message);
                            SmsSender.INSTANCE.sendMsg(mpi.getPhone(), message);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    /**
     * 初始化
     */
    private void initialize() {
        JideTabbedPane tabbedPane = new JideTabbedPane();
        this.add(tabbedPane, BorderLayout.CENTER);

        DaqPane dp = new DaqPane();
        this.addDataArriveListener(dp.getDataArriveListener());
        tabbedPane.addTab("实时数据", dp);

        DaqGrid dg = new DaqGrid();
        this.addDataArriveListener(dg.getDataArriveListener());
        tabbedPane.addTab("表格数据", dg);

        QueryDataGrid qdg = new QueryDataGrid();
        tabbedPane.addTab("查询", qdg);

        tabbedPane.addTab("联系人", new LinkmanPane());

        tabbedPane.addTab("值班人员", new WatchKeeperEditor());
    }

    /**
     * 添加数据到达监听器
     * 
     * @param lstnr
     *            数据到达监听
     */
    public synchronized void addDataArriveListener(IDataArriveListener lstnr) {
        this.listenerList.add(lstnr);
    }

    /**
     * 移除数据到达监听器
     * 
     * @param lstnr
     *            数据到达监听器
     */
    public synchronized void removeDataArriveListener(IDataArriveListener lstnr) {
        this.listenerList.remove(lstnr);
    }

    // 触发事件
    public void fireEvent(DataArriveEvent event) {
        for (IDataArriveListener lstnr : this.listenerList) {
            lstnr.dataArrive(event);
        }
    }

    // 启动定时数据采集
    private void initPeriodicDaq() {
        try {
            Properties prop = new Properties();
            prop.load(new FileInputStream("mtr.properties"));
            String queryTime = prop.getProperty("query_time");

            System.out.println("初始化数据采集：" + queryTime);
            QuartzManager.INSTANCE.addJob("DATA_QUERY", DaqJob.class, queryTime);

            QuartzManager.INSTANCE.startJobs();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onSerialEvent(SerialEvent event) {
        String data = event.getData();
        if (data.length() >= DATA_LENGTH) {
            bufferData = "";

            System.out.println("收到数据：" + data);
            dealData(data);
        } else {
            bufferData += data;
            if (bufferData.length() >= DATA_LENGTH) {
                dealData(bufferData);

                System.out.println("收到数据：" + bufferData);
                bufferData = "";
            }
        }
    }

    /**
     * 处理温度数据数据
     * 
     * @param data
     *            数据
     */
    private void dealData(String data) {
        String channel = data.substring(0, 1);
        String value = data.substring(1);

        Record rec = new Record();
        rec.setChannel(channel);
        rec.setValue(NumberUtils.convertToDouble(value.replaceAll(" ", ""), 0));
        rec.setTime(new Timestamp(System.currentTimeMillis()));

        dao.insert(rec);
        // 发送短信
        double v = rec.getValue();
        if ((v > 6.1) && (v < 80)) {
            SmsRecord r = new SmsRecord(channel, v);

            try {
                this.smsQuery.put(r);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        this.fireEvent(new DataArriveEvent(this, channel, rec));
    }
}
